package com.lm56.web.waybill.service;

import com.lm56.common.exception.*;
import com.lm56.common.MyRequestBody;
import com.lm56.web.waybill.domain.WaybillProcessForm;
import com.lm56.web.waybill.domain.WaybillQueryParams;
import com.lm56.web.waybill.domain.WaybillTraceDTO2;
import com.lm56.web.CommonService;
import com.lm56.web.sys.domain.User;
import com.lm56.web.sys.domain.UserDetail;
import com.lm56.web.sys.service.UserService;
import com.lm56.web.waybill.mapper.WaybillMapper;
import com.lm56.web.security.SecUserDetails;
import com.lm56.web.waybill.domain.GoodsInfo;
import com.lm56.web.waybill.domain.Waybill;
import com.lm56.web.waybill.domain.WaybillTrace;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by Kelvin Yeung on 2016/11/9.
 */
@Component
@Transactional
public class WaybillService {

    @Autowired
    WaybillMapper waybillMapper;
    @Autowired
    UserService userService;

    @Autowired
    CommonService commonService;

    /**
     * 新增订单
     * 分两种情况，1.发货人新增订单，2 公司新增订单
     *
     * @param waybill
     */
    public void newWaybill(Waybill waybill) {


        SecUserDetails secUser = (SecUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        UserDetail user = userService.getUserDetailByPhoneNo(secUser.getUsername());

        //根据运单号和公司ID对比，看看数据库是否已存在订单
        //分两种情况：1填写的托运公司未在平台注册的，2.填写的托运公司已在平台注册的
        //先判断是否托运公司填写的运单
        if(user.getUserType()== User.USER_TYPE_COMPANY){
            waybill.setOriginType(Waybill.ORIGIN_TYPE_COMPANY);

            //公司填写的订单号不能为空；
            if(StringUtils.isBlank(waybill.getWaybillNo()))
            {
                throw new FieldValidateExcetiption("waybillNo","运单号不能为空");
            }


        }else{
//            if(user.getUserType()==User.USER_TYPE_SENDER){
//                waybill.setSenderId(user.getId());
//            }
            waybill.setSenderId(user.getId());
            waybill.setOriginType(Waybill.ORIGIN_TYPE_COMPANY);

        }

        //不分公司还是发货人，只有订单号和公司ID相同才认为是订单已存在
        //判断是否已存在订单；根据公司ID和订单号；
        try {
            Waybill hasWaybill = waybillMapper.getWaybillForCompany(waybill.getCompanyId(), null, waybill.getWaybillNo());
            if (hasWaybill != null) {
                throw new FieldValidateExcetiption("waybillNo", "订单已存在");
            }
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw new RuntimeException("未知错误");
        }



        waybill.setLastCompanyId(0L);
        waybill.setWaybillStatus(Waybill.STATUS_NEW);
        waybill.setStatus(Waybill.STATUS_NEW);



       //插入waybill
        waybillMapper.insertWaybill(waybill);
        //插入waybill_company
        waybillMapper.insertWaybillCompany(waybill);
        //插入waybill_goods
        for(GoodsInfo goodsInfo:waybill.getGoods()){
            goodsInfo.setWaybillId(waybill.getWaybillId());
        }
        waybillMapper.insertWaybillGoods(waybill.getGoods());



    }


    /**
     * 公司获取运单列表
     * @param requestBody
     * RequestBody 的startIndex,endIndex 必须
     * WaybillQueryParams 的 companyId 必须
     *              waybillNo 可选,senderPhoneNo 可选,waybillStatus 必须,isRecycle 必须
     * @return
     */
    public List<Waybill> getWaybillsForCompany(MyRequestBody<WaybillQueryParams> requestBody) {

        return waybillMapper.getWaybillsForCompany(requestBody);
    }
    /**
     * 公司获取运单列表
     * @param requestBody
     * RequestBody 的startIndex,endIndex 必须
     * WaybillQueryParams 的 companyId 必须
     *              waybillNo 可选,senderPhoneNo 可选,waybillStatus 必须,isRecycle 必须
     * @return
     */
    public Integer getWaybillsCountForCompany(MyRequestBody<WaybillQueryParams> requestBody) {

        return waybillMapper.getWaybillsCountForCompany(requestBody);
    }


    /**
     * 发货人
     * @param requestBody
     * RequestBody 的startIndex,endIndex 必须
     * WaybillQueryParams 的 senderId 必须,,isRecycle 必须
     * @return
     */
    public  List<Waybill> getWaybillsForSender(MyRequestBody<WaybillQueryParams> requestBody){
        return waybillMapper.getWaybillsForSender(requestBody);
    }


    /**
     * 发货人获取运单详情
     * @param senderId
     * @param waybillId
     * @return
     */
    public Waybill getWaybillDetailsForSender(Long senderId, Long waybillId){
        return waybillMapper.getWaybillDetailsForSender( senderId, waybillId);
    }

    /**
     * 公司获取运单详情
     * @param companyId
     * @param waybillId
     * @return
     */
    public Waybill getWaybillDetailsForCompany( Long companyId,Long waybillId){
           return  waybillMapper.getWaybillDetailsForCompany(companyId, waybillId);
    }



    public List<WaybillTraceDTO2> getWaybillTraceById(Long waybillId){
        return waybillMapper.getWaybillTraceById(waybillId);
    }


    public void updateWaybill(Waybill waybill){
        SecUserDetails user = (SecUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        //先断判waybill是否存在
        Waybill tmpWaybill = waybillMapper.getWaybillForCompany(user.getUserId(), waybill.getWaybillId(), null);
        if(tmpWaybill == null){
            throw new FieldValidateExcetiption("订单不存在");
        }
        waybillMapper.updateWaybill(waybill);
        //对于货物，先删除后插入
        waybillMapper.updateWaybillCompany(waybill);
        waybillMapper.deleteWaybillGoodsByWaybillId(waybill.getWaybillId());
        //插入waybill_goods
        for(GoodsInfo goodsInfo:waybill.getGoods()){
            goodsInfo.setWaybillId(waybill.getWaybillId());
        }
        waybillMapper.insertWaybillGoods(waybill.getGoods());

    }

    public void processWaybill(WaybillProcessForm processForm){
        SecUserDetails secUser = (SecUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //TODO:首先确认waybillId是否存在
        Waybill waybill = waybillMapper.getWaybillForCompany(secUser.getUserId(), processForm.getWaybillId(), null);
        if(waybill==null){
            throw new WaybillNotFoundException("订单不存在");
        }

        if(waybill.getWaybillStatus()==Waybill.STATUS_TRANSSHIPPED){
            throw new WaybillProcessException("订单已中转，不能再进行中转");
        }
        if(waybill.getWaybillStatus()==Waybill.STATUS_SIGN || waybill.getStatus()==Waybill.STATUS_SIGN){
            throw new WaybillProcessException("订单已签收,不能再处理");
        }
        if(StringUtils.isBlank(processForm.getRemark())){
            throw new FieldValidateExcetiption("备注不能为空");
        }

        //如果是中转，需在Waybill_company插入相应信息
        if(processForm.getProcessId()==Waybill.STATUS_TRANSSHIPPED){
            //1.检查单号是否已存在
            WaybillQueryParams queryForm = new WaybillQueryParams();
            queryForm.setWaybillNo(processForm.getWaybillNo());
            if(processForm.getCompanyId() == null){
                processForm.setCompanyId(0L);
                queryForm.setCompanyId(0);
            }else{

                queryForm.setCompanyId(processForm.getCompanyId());
            }
            queryForm.setCompanyName(processForm.getCompanyName());

            //TODO:
             Waybill existWaybill = waybillMapper.getWaybillForCompany(queryForm.getCompanyId(),processForm.getWaybillId(),queryForm.getWaybillNo());
            if(existWaybill  != null){
                //TODO:是否只限制一个订单跟踪里订单号不能重复？
                throw  new WaybillAlreadyExistsExction("中转的单号已存在");
            }

            //2.检查公司Id是否正确
            if(processForm.getCompanyId()>0){
                User company = userService.getUserById(processForm.getCompanyId());
                if(company != null){
                        throw new UserNotFoundException("所选择的公司错误");
                }
            }
            //3.检查电话号码不能为空
            if(StringUtils.isBlank(processForm.getPhoneNo())){
                throw new FieldValidateExcetiption("电话号码不能为空");
            }
            //4.日期时间


            //插入waybill_company记录
           Waybill wc = new Waybill();
            wc.setWaybillId(processForm.getWaybillId());
            wc.setWaybillNo(processForm.getWaybillNo());
            wc.setCompanyId(processForm.getCompanyId());

            wc.setCompanyName(processForm.getCompanyName());
            wc.setLastCompanyId(secUser.getUserId());
            wc.setCompanyAddr(processForm.getAddress());
            wc.setCompanyPhoneNo1(processForm.getPhoneNo());
            wc.setWaybillStatus(Waybill.STATUS_NEW);
            wc.setWaybillFee(processForm.getFee());
            wc.setOriginType(Waybill.ORIGIN_TYPE_TRANSFER);
            waybillMapper.insertWaybillCompany(wc);



        }else{
            User user = userService.getUserById(secUser.getUserId());
            processForm.setCompanyId(user.getId());
            processForm.setCompanyName(user.getUserName());

        }

        //插入waybill_trace记录
        WaybillTrace wt = new WaybillTrace();
        wt.setWaybillId(processForm.getWaybillId());
        wt.setWaybillNo(processForm.getWaybillNo());
        wt.setCompanyId(processForm.getCompanyId());
        wt.setCompanyName(processForm.getCompanyName());
        wt.setOperateTime(processForm.getSendDate());
        wt.setOperateType(processForm.getProcessId());
        wt.setRemark(processForm.getRemark());
        waybillMapper.insertWaybillTrace(wt);

        //更新处理公司的运单状态
        Waybill wc2 = new Waybill();
        wc2.setWaybillId(processForm.getWaybillId());
        wc2.setCompanyId(secUser.getUserId());
        wc2.setWaybillStatus(processForm.getProcessId());
        waybillMapper.updateWaybillCompanyStatus(wc2);

        //更新运单的状态
        waybillMapper.updateWaybillStatus(wc2.getWaybillId(),wc2.getWaybillStatus());


    }


    /**
     * 还原运单
     * @param waybill
     */
    public void restoreWaybill(Waybill waybill){
        waybill.setIsRecycle(Waybill.IS_NORMAL);
        waybillMapper.updateWaybillRecycleInd(waybill);
    }

    /**
     * 批量还原运单
     * @param waybillIds
     */
    public void restoreWaybills(List<Long> waybillIds){
        SecUserDetails user = (SecUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(user.getUserType() == User.USER_TYPE_COMPANY){
            waybillMapper.updateWaybillsRecycleInd(user.getUserId(), waybillIds, Waybill.IS_NORMAL);
        }else{
            waybillMapper.updateWaybillsRecycleIndForSender(user.getUserId(),waybillIds,Waybill.IS_NORMAL);
        }


    }

    /**
     * 放入回收站
     * @param waybill
     */
    public void moveWaybillToRecycleBin(Waybill waybill){
        waybill.setIsRecycle(Waybill.IS_RECYCLING);
        waybillMapper.updateWaybillRecycleInd(waybill);
    }
    /**
     * 批量放入回收站
     * @param waybillIds
     */
    public void moveWaybillsToRecycleBin(List<Long> waybillIds){
        SecUserDetails user = (SecUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(user.getUserType() ==User.USER_TYPE_COMPANY){
            waybillMapper.updateWaybillsRecycleInd(user.getUserId(), waybillIds, Waybill.IS_RECYCLING);
        }else{
            waybillMapper.updateWaybillsRecycleIndForSender(user.getUserId(), waybillIds, Waybill.IS_RECYCLING);

        }
    }

    /**
     * 删除运单
     * 不做物理删除，只把标志位更改为删除标识
     * @param waybillIds
     */
    public void deleteWaybills(List<Long> waybillIds){
        SecUserDetails user = (SecUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(user.getUserType() == User.USER_TYPE_COMPANY){
            waybillMapper.updateWaybillsRecycleInd(user.getUserId(), waybillIds, Waybill.IS_DELETED);
        }else{
            waybillMapper.updateWaybillsRecycleIndForSender(user.getUserId(),waybillIds,Waybill.IS_DELETED);
        }
    }

}
